/**
 * tron_tx.cpp
 *
 * This programs transmits the on/off packets.
 *
 * Author: Charles DuHadway
 * email: duhadway@gmail.com


 * TODO:
 *   X get serial transmision working	
 *   X get port2 buttons working
 *   X get all button working
 *   X add debounce logic
 *   turn BIT6 back to input
 *   look at internal pull-up resistors (P1REN)
 */

#include "../common.h"
#include <msp430g2553.h>
#include <legacymsp430.h>
#include <stdint.h>

// PORT 1
#define ALL BIT0

#define HANSEL BIT1
#define ALAN BIT3
#define SETH BIT4
#define CHARLES BIT5

#define GUZEL BIT6
#define LAURA BIT7

// PORT 2
#define KEN BIT0
#define DAVE BIT1

#define KRISTINA BIT2
#define MARIA BIT3
#define LINDA BIT4
#define KELLY BIT5

//uint8_t p1_buttons = (ALL | HANSEL | ALAN | SETH | CHARLES | GUZEL | LAURA);
uint8_t p1_buttons = (ALL | HANSEL | ALAN | SETH | CHARLES | LAURA);
uint8_t p2_buttons = (KEN | DAVE | KRISTINA | MARIA | LINDA | KELLY);

uint8_t alan = 1;
uint8_t charles = 1;
uint8_t dave = 1;
uint8_t hansel = 1;
uint8_t ken = 1;
uint8_t seth = 1;

uint8_t guzel = 1;
uint8_t kelly = 1;
uint8_t kristina = 1;
uint8_t laura = 1;
uint8_t linda = 1;
uint8_t maria = 1;

uint8_t all = 0x0;

long int debounce_count = 0;

void serial_xmit(uint8_t c) {
  while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer 
  UCA0TXBUF = (uint8_t) c;     // TX -> RXed character
  _NOP();
}

int check_p1_interrupt(uint8_t bit, uint8_t* button) {
  if (P1IFG & bit) {
    P1IFG &= ~bit;
    *button = !(*button);
    return 1;
  }
  return 0;
}

int check_p2_interrupt(uint8_t bit, uint8_t* button) {
  if (P2IFG & bit) {
    P2IFG &= ~bit;
    *button = !(*button);
    return 1;
  }
  return 0;
}

void interrupt_handler(void) {

  if (debounce_count > 0) {    
    P1IFG = 0x0;
    P2IFG = 0x0;
    _NOP();
    return;
  }

  debounce_count = 10;

  check_p1_interrupt(HANSEL, &hansel);
  check_p1_interrupt(ALAN, &alan);
  check_p1_interrupt(SETH, &seth);
  check_p1_interrupt(CHARLES, &charles);
  check_p2_interrupt(DAVE, &dave);
  check_p2_interrupt(KEN, &ken);

  check_p1_interrupt(GUZEL, &guzel);
  check_p1_interrupt(LAURA, &laura);
  check_p2_interrupt(KRISTINA, &kristina);
  check_p2_interrupt(MARIA, &maria);
  check_p2_interrupt(KELLY, &kelly);
  check_p2_interrupt(LINDA, &linda);

  if (check_p1_interrupt(ALL, &all)) {
    charles = all;
    alan =    all;
    hansel =  all;
    seth =    all;
    dave =    all;
    ken =     all;

    guzel =    all;
    kelly =    all;
    kristina = all;
    laura =    all;
    linda =    all;  
    maria =    all;    
  }
}


int main(void)
{
  WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
 
  BCSCTL1 = CALBC1_8MHZ;
  DCOCTL = CALDCO_8MHZ;

  P1SEL = BIT2;  // P1.2=TXD
  P1SEL2 = BIT2; // P1.2=TXD

  UCA0CTL1 = 0;		// Resetting to known state (nothing)
  UCA0CTL1 |= UCSSEL_2; // use SMCLK for USCI clock

  UCA0BR0 = 104 & 0xFF;        // 8MHz 4800
  UCA0BR1 = 104 >> 8;          // 8MHz 4800

  UCA0MCTL = 0x1; // UCOS16 = 1 , UCBRS=0, 

  UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
  IE2 |= UCA0RXIE;      // Enable USCI0RX_ISR interrupt

  P1DIR = ~p1_buttons; // (BIT0 | BIT6); // Set P1 buttons input
  P2DIR = ~p2_buttons; // 0x0;           // Set P1 buttons input

  P1IE = p1_buttons; // P1 buttons interrupt enabled
  P2IE = p2_buttons; // P2 buttons interrupt enabled

  P1IES = ~p1_buttons;
  P2IES = ~p2_buttons;

  P1IFG &= ~p1_buttons; // P1 IFG cleared
  P2IFG &= ~p2_buttons; // P2 IFG cleared

  P1OUT |= (BIT0);

  __bis_SR_register(GIE);  // Enable interrupts.

  debounce_count = 0;

  while (1) {
    debounce_count = (debounce_count > 0) ? debounce_count - 1 : 0;

    serial_xmit(FILLER);

    if (charles) {
      P1OUT |= BIT6;
    } else {
      P1OUT &= ~BIT6;
    }

    if (alan)    serial_xmit(ALAN_ON); else    serial_xmit(ALAN_OFF);
    if (charles) serial_xmit(CHARLES_ON); else serial_xmit(CHARLES_OFF);
    if (dave)    serial_xmit(DAVE_ON); else    serial_xmit(DAVE_OFF);
    if (hansel)  serial_xmit(HANSEL_ON); else  serial_xmit(HANSEL_OFF);
    if (ken)     serial_xmit(KEN_ON); else     serial_xmit(KEN_OFF);
    if (seth)    serial_xmit(SETH_ON); else    serial_xmit(SETH_OFF);

    if (guzel)    serial_xmit(GUZEL_ON); else    serial_xmit(GUZEL_OFF);
    if (kelly)    serial_xmit(KELLY_ON); else    serial_xmit(KELLY_OFF);
    if (kristina) serial_xmit(KRISTINA_ON); else serial_xmit(KRISTINA_OFF);
    if (laura)    serial_xmit(LAURA_ON); else    serial_xmit(LAURA_OFF);
    if (linda)    serial_xmit(LINDA_ON); else    serial_xmit(LINDA_OFF);
    if (maria)    serial_xmit(MARIA_ON); else    serial_xmit(MARIA_OFF);
  }
  return 0;
}

interrupt(PORT1_VECTOR) Port_1(void)
{
  interrupt_handler();
}

interrupt(PORT2_VECTOR) Port_2(void)
{
  interrupt_handler();
}

